/* 
gulp依赖包函数方法介绍

    gulp.src()
        导入要执行压缩规范的文件
        注意：只能导入 文件 不能导入 文件夹
        *.css 所有的css文件
        *.* 所有文件
        **
    
    gulp.dest()
        将指定文件 存储到 指定文件夹
        只能执行文件的存储写入 不能执行文件的删除操作

    gulp.watch(参数1，参数2)
        参数1 要监听的文件路径
        参数2 监听文件内容改变 触发的函数程序 参数2 是函数名称的语法

    pipe()
        和 gulp.src() 绑定使用的
        对 gulp.src() 导入的文件 执行指定的函数程序
            gulp.src().pipe(执行的函数程序).pipe(执行的函数程序)....

    gulp.series()
        按照顺序执行 定义的函数程序

    gulp.parallel()
        提示执行 定义的函数程序

    module.exports.default = 函数程序
        设定 gulp 默认执行的函数程序
        之前 运行文件语法是node文件名.js
        导入默认程序后执行gulp程序的语法形式 gulp回车执行
        默认找到gulpfile.js 文件执行 module.exports.default 对应的函数程序
*/

//  1. 加载导入 相关的依赖包 - 导入直接按照依赖包名称导入

// 导入gulp依赖包 - 本质是对象 - 其中 有属性属性值和函数方法
// 导入的gulp打包压缩规范依赖包 本质是一个函数程序 - 依赖包() 就是调用执行这个函数程序
const gulp = require('gulp')

// 导入sass依赖包
const autoprefixer = require('gulp-autoprefixer')
const cssmin = require('gulp-cssmin')

// 一、导入js依赖包
// 下载4个依赖包 导入2个依赖包 - @babel/core @babel/preset-env 是 gulp-babel 导入
const babel = require('gulp-babel')
const uglify = require('gulp-uglify')

// 导入html依赖包
const htmlmin = require('gulp-htmlmin')

// 导入删除依赖包
const del = require('del')

// 导入服务器依赖包
const webserver = require('gulp-webserver')

// 导入sass依赖包
const sass = require('gulp-sass')

// 二、 设定gulp 打包压缩规范

// 1-1. css打包压缩规范
const cssHandler = function() {
    // 通过 return 导入需要执行的指定程序
    return gulp.src('./src/css/*.css') //通过gulp.src()导入要执行打包压缩的文件
        .pipe(autoprefixer()) // 对 gulp.src() 导入的文件 执行 添加css兼容前缀的第三方打包压缩规范依赖包程序
        .pipe(cssmin()) //导入的文件 执行 添加css打包压缩的第三方打包压缩规范依赖包程序
        .pipe(gulp.dest('./dist/css')) //对 gulp.src() 导入的文件 存储到指定的文件夹中
}

// 1-2, sass打包压缩规范
// 先将 sass文件编译成 css文件
// 再执行 css文件的 打包规范
// 实际项目中 sass类型的文件 和 css类型的文件不会同时使用
const sassHandler = function() {
    // 通过 return 导入需要执行的指定程序
    return gulp.src('./src/sass/*.scss') //  通过 gulp.src() 导入 要执行 打包压缩规范的文件
        .pipe(sass()) //  对 gulp.src() 导入的文件 编译转化为css格式的文件
        .pipe(autoprefixer()) //  对 gulp.src() 导入的文件 执行 添加css兼容前缀的第三方打包压缩规范依赖包程序
        .pipe(cssmin()) //  对 gulp.src() 导入的文件 执行 添加css打包压缩的第三方打包压缩规范依赖包程序
        .pipe(gulp.dest('./dist/css')); //  对 gulp.src() 导入的文件 存储到指定的文件夹中
}

// 1-3, js打包压缩规范
// 先其他版本js语法转化为ES5版本的js语法
// 再打包压缩js文件
const jsHandler = function() {
    // 通过 return 导入需要执行的指定程序
    return gulp.src('./src/js/*.js') //  通过 gulp.src() 导入 要执行 打包压缩规范的文件
        .pipe(babel({ presets: ['@babel/env'] })) //  对 gulp.src() 导入的文件 编译成ES5版本的js程序 需要设定固定的参数形式
        .pipe(uglify()) //  对 gulp.src() 导入的文件 执行打包压缩程序
        .pipe(gulp.dest('./dist/js')); //  对 gulp.src() 导入的文件 存储到指定的文件夹中
}

// 1-4, html打包压缩规范
// 需要配置html打包压缩参数
const htmlHandler = function() {
    // 通过 return 导入需要执行的指定程序
    return gulp.src('./src/*.html') //  通过 gulp.src() 导入 要执行 打包压缩规范的文件
        .pipe(htmlmin({ //  对 gulp.src() 导入的文件 执行html打包压缩规范 需要设定固定的参数形式
            removeAttributeQuotes: true, //  删除属性中的双引号
            removeComments: true, //  删除注释
            removeEmptyAttributes: true, //  删除空属性
            // removeEmptyElements:true,                //  删除空标签
            removeScriptTypeAttributes: true, //  删除script标签中定义的type属性
            // removeStyleLinkTypeAttributes: true, //  删除style标签,link标签 type属性
            collapseBooleanAttributes: true, //  删除布尔属性的属性值
            collapseWhitespace: true, //  删除标签之间的空格
            minifyCSS: true, //  压缩内部css程序
            minifyJS: true, //  压缩内部js程序
        }))
        .pipe(gulp.dest('./dist')); //  对 gulp.src() 导入的文件 存储到指定的文件夹中
}


// 不需要压缩 直接 存储到 dist 对应的文件夹中就可以了

// 1-5, 图片文件
const imgHandler = function() {
    return gulp.src('./src/images/*.*') //  通过 gulp.src() 导入 要执行 打包压缩规范的文件
        .pipe(gulp.dest('./dist/images')); //  对 gulp.src() 导入的文件 存储到指定的文件夹中
}

// 1-6, php文件
// const phpHandler = function() {
//     return gulp.src('./src/server/*.php') //  通过 gulp.src() 导入 要执行 打包压缩规范的文件
//         .pipe(gulp.dest('./dist/server')); //  对 gulp.src() 导入的文件 存储到指定的文件夹中
// }

// 1-5, 图片文件
const jsonHandler = function() {
    return gulp.src('./src/json/*.json') //  通过 gulp.src() 导入 要执行 打包压缩规范的文件
        .pipe(gulp.dest('./dist/json')); //  对 gulp.src() 导入的文件 存储到指定的文件夹中
}

// // 1-7, 其他打包压缩好的js文件
// const toolsHandler = function() {
//     return gulp.src('./src/tools/**') //  通过 gulp.src() 导入 要执行 打包压缩规范的文件
//         .pipe(gulp.dest('./dist/tools')); //  对 gulp.src() 导入的文件 存储到指定的文件夹中
// }

// 2. 设定删除规范

const delHandler = function() {
    // del([路径1,路径2,...]) - 以数组形式设定参数 - 参数是要删除的文件夹路径 - 没有文件夹也不会报错
    return del(['./dist'])
}

//  服务器规范
// gulp中提供的服务器规范 不能完成正式服务的所有功能
// 实际项目中不会使用 gulp 提供的服务器规范 搭建服务器
// 当前 主要是为了演示 热启动
const webserverHandler = function() {
    return gulp.src('./dist')
        .pipe(webserver({
            host: '127.0.0.1', //  设定服务器地址 当前是本地电脑上搭建服务器
            port: '8888', //  设定服务器端口
            open: './home.html', //  设定默认打开的文件内容 相对路径是从 gulp.src() 导入的文件路径计算起始
            livereload: true, //  开启热启动  文件内容改变 服务器自动刷新页面 不用用户手动刷新
        }))
}

// 3. 设定监听规范
const watchHandler = function() {
    // 当src文件中css文件内容变化就会触发执行cssHandler
    gulp.watch('./src/css/*.css', cssHandler)
        // 将 scr文件中sass文件夹中扩展名是scss的文件内容改变时 执行 sassHandler 函数程序
        // 也就是当 源文件 中 sass文件内容改变 触发执行 sass打包压缩规范
    gulp.watch('./src/sass/*.scss', sassHandler);

    // 将 scr文件中js文件夹中扩展名是js的文件内容改变时 执行 jsHandler 函数程序
    // 也就是当 源文件 中 js文件内容改变 触发执行 js打包压缩规范
    gulp.watch('./src/js/*.js', jsHandler);

    // 将 scr文件中js文件夹中扩展名是js的文件内容改变时 执行 jsHandler 函数程序
    // 也就是当 源文件 中 js文件内容改变 触发执行 js打包压缩规范
    gulp.watch('./src/*.html', htmlHandler);


    gulp.watch('./src/images/*.*', imgHandler);
    gulp.watch('./src/server/*.php', jsonHandler);
    // gulp.watch('./src/tools/**', toolsHandler);

}

// 4. 设定默认执行程序
// 运行 gulp 就会触发执行 默认函数程序
module.exports.default = gulp.series(
    // 打包压缩之前 先删除有可能有多余文件的上一次压缩过的文件
    delHandler,
    // 先打包文件 - 同时执行 gulp.parallel()中的函数程序
    gulp.parallel(cssHandler, sassHandler, jsHandler, htmlHandler, imgHandler, jsonHandler),
    webserverHandler,
    // 监听源文件内容变化
    watchHandler,

)